package com.rf.richfitwheel.admin.executor.service.jobhandler;

import com.rf.richfitwheel.admin.iam.service.PortalOrgService;
import com.rf.richfitwheel.admin.iam.service.PortalRoleMemberService;
import com.rf.richfitwheel.admin.iam.service.PortalUsbKeyService;
import com.rf.richfitwheel.admin.iam.service.PortalUserService;
import com.rf.richfitwheel.admin.sys.model.Config;
import com.rf.richfitwheel.admin.sys.service.ConfigService;
import com.rf.richfitwheel.admin.sys.vo.UserVO;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author hushouquan
 */
@Component
public class IamSynJobHandler{
    private Logger log = LoggerFactory.getLogger(IamSynJobHandler.class);
    
    @Autowired
    private PortalOrgService portalOrgService;
    @Autowired
    private PortalUserService portalUserService;
    @Autowired
    private PortalRoleMemberService portalRoleMemberService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private PortalUsbKeyService portalUsbKeyService;
    /**
     * 组织机构同步任务，同步入库+处理
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("orgSynHandler")
    public ReturnT<String> orgSynHandler(String param){
        //数据同步的游标,初始游标，在同步入库中不再进行游标存取，减少数据查询
        Config config = configService.getParamVlueByKey("IAM_ORGS_SYNC_CURSOR");
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //入库时间
            long myDate = new Date().getTime();
            log.info("开始执行组织机构数据同步................");
            long start = System.currentTimeMillis();
            //同步数据总条数
            Integer countSyn = 0;
            //调用接口同步数据并入库
            countSyn = portalOrgService.orgSynDo(pj.getString("appId"), myDate, config, countSyn);
            long end = System.currentTimeMillis();
            log.info("执行组织机构数据同步完成，共同步{}条数据，用时{}秒................", countSyn, (end-start)/1000);
            //处理入库后的数据
            log.info("开始执行组织机构数据更新................");
            long start1 = System.currentTimeMillis();
            portalOrgService.orgDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行组织机构数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，共同步" + countSyn + "条数据，用时" + (end-start)/1000 + "秒。执行数据更新成功共用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }finally{
            UserVO user = new UserVO();
            user.setId("1");
            configService.update(config, user);
        }
    }
    
    /**
     * 组织机构同步任务，已入库的情况下进行处理
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("orgManageHandler")
    public ReturnT<String> orgManageHandler(String param){
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //入库时间
            long myDate = pj.getLong("myDate");
            //处理入库后的数据
            log.info("开始执行组织机构数据更新................");
            long start1 = System.currentTimeMillis();
            portalOrgService.orgDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行组织机构数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }
    }
    
    /**
     * 用户同步任务
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("usersSynHandler")
    public ReturnT<String> usersSynHandler(String param){
        //数据同步的游标,初始游标，在同步入库中不再进行游标存取，减少数据查询
        Config config = null;
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            config = configService.getParamVlueByKey(pj.getString("cursorKey"));
            //入库时间
            long myDate = new Date().getTime();
            log.info("开始执行用户数据同步................");
            long start = System.currentTimeMillis();
            //同步数据总条数
            Integer countSyn = 0;
            //调用接口同步数据并入库
            countSyn = portalUserService.userSynDo(pj.getString("appId"), myDate, config, countSyn);
            long end = System.currentTimeMillis();
            log.info("执行用户数据同步完成，共同步{}条数据，用时{}秒................", countSyn, (end-start)/1000);
            //处理入库后的数据
            log.info("开始执行用户数据更新................");
            long start1 = System.currentTimeMillis();
            portalUserService.userDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行用户数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，共同步" + countSyn + "条数据，用时" + (end-start)/1000 + "秒。执行数据更新成功共用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }finally{
            UserVO user = new UserVO();
            user.setId("1");
            if(config != null){
                configService.update(config, user);
            }
        }
    }
    
    /**
     * 当同步成功入库后续处理失败时单独处理用户
     * @param param 参数
     * @return 结果
     */
    @XxlJob("usersManageHandler")
    public ReturnT<String> usersManageHandler(String param){
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //处理入库后的数据
            log.info("开始执行用户数据更新................");
            //入库时间
            long myDate = pj.getLong("myDate");
            long start1 = System.currentTimeMillis();
            portalUserService.userDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行用户数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }
    }
    /**
     * 角色上报任务
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("rolesSynHandler")
    public ReturnT<String> rolesSynHandler(String param){
        try{
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }
    }
    
    /**
     * 用户角色绑定任务
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("roleMemberSynHandler")
    public ReturnT<String> roleMemberSynHandler(String param){
        //数据同步的游标
        Config config = null;
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            config = configService.getParamVlueByKey(pj.getString("cursorKey"));
            //入库时间
            long myDate = new Date().getTime();
            log.info("开始执行用户角色绑定任务................");
            long start = System.currentTimeMillis();
            //同步数据总条数
            Integer countSyn = 0;
            //调用接口同步数据并入库
            countSyn = portalRoleMemberService.roleMemberSynDo(pj.getString("appId"), myDate, config, countSyn);
            long end = System.currentTimeMillis();
            log.info("执行用户角色绑定任务完成，共同步{}条记录，用时{}秒................", countSyn, (end-start)/1000);
            //处理入库后的数据
            log.info("开始执行用户角色绑定任务更新................");
            long start1 = System.currentTimeMillis();
            portalRoleMemberService.roleMemberDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行用户角色绑定任务更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，共同步" + countSyn + "条数据，用时" + (end-start)/1000 + "秒。执行数据更新成功共用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }finally{
            UserVO user = new UserVO();
            user.setId("1");
            if(config != null){
                configService.update(config, user);
            }
        }
    }
    
    /**
     * 用户角色绑定任务
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("roleMemberManageHandler")
    public ReturnT<String> roleMemberManageHandler(String param){
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //入库时间
            long myDate = pj.getLong("myDate");
            //处理入库后的数据
            log.info("开始执行用户角色绑定任务更新................");
            long start1 = System.currentTimeMillis();
            portalRoleMemberService.roleMemberDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行用户角色绑定任务更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，用时" + (end1-start1)/1000 +"秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }
    }
    
    /**
     * ukey信息同步
     * @param param 参数
     * @return
     */
    @XxlJob("usbKeySynHandler")
    public ReturnT<String> usbKeySynHandler(String param){
        //数据同步的游标,初始游标，在同步入库中不再进行游标存取，减少数据查询
        Config config = null;
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //"IAM_USB_KEY_SYNC_CURSOR_JS"
            config = configService.getParamVlueByKey(pj.getString("cursorKey"));
            //入库时间
            long myDate = new Date().getTime();
            log.info("开始执行usb key数据同步................");
            long start = System.currentTimeMillis();
            //同步数据总条数
            Integer countSyn = 0;
            //调用接口同步数据并入库
            countSyn = portalUsbKeyService.usbKeySynDo(pj.getString("appId"), myDate, config, countSyn);
            long end = System.currentTimeMillis();
            log.info("执行usb key数据同步完成，共同步{}条数据，用时{}秒................", countSyn, (end-start)/1000);
            //处理入库后的数据
            log.info("开始执行usb key数据更新................");
            long start1 = System.currentTimeMillis();
            portalUsbKeyService.usbKeyDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行usb key数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，共同步" + countSyn + "条数据，用时" + (end-start)/1000 + "秒。执行组织机构数据更新成功共用时" + (end1-start1)/1000 + "秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }finally{
            UserVO user = new UserVO();
            user.setId("1");
            configService.update(config, user);
}
    }
    
    /**
     * usb key同步任务，已入库的情况下进行处理
     *
     * @param param 参数
     * @return 任务执行结果
     */
    @XxlJob("usbKeyManageHandler")
    public ReturnT<String> usbKeyManageHandler(String param){
        try{
            param = XxlJobHelper.getJobParam();
            JSONObject pj = JSONObject.fromObject(param);
            //入库时间
            long myDate = pj.getLong("myDate");
            //处理入库后的数据
            log.info("开始执行usb key数据更新................");
            long start1 = System.currentTimeMillis();
            portalUsbKeyService.usbKeyDeal(myDate);
            long end1 = System.currentTimeMillis();
            log.info("执行usb key数据更新完成，共用时{}秒................", (end1-start1)/1000);
            return new ReturnT<>(HttpStatus.OK.value(), "执行成功，用时" + (end1-start1)/1000 +"秒。");
        }catch(Exception e){
            log.error("执行失败", e);
            return new ReturnT<>(ReturnT.FAIL_CODE, "" + e);
        }
    }
}
